package com.tool4j.service.impl;

import cn.hutool.core.util.StrUtil;
import com.tool4j.common.Constants;
import com.tool4j.common.LoginTypeEnum;
import com.tool4j.entity.User;
import com.tool4j.entity.params.LoginParams;
import com.tool4j.entity.vo.LoginResponse;
import com.tool4j.entity.vo.UserDetail;
import com.tool4j.service.AuthService;
import com.tool4j.service.MailService;
import com.tool4j.service.UserService;
import com.tool4j.util.CacheUtil;
import com.tool4j.util.JwtUtil;
import com.tool4j.util.SpringUtil;
import com.tool4j.util.UserPermission;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.web.server.ServerWebExchange;

import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Deng.Weiping
 * @since 2023/10/31 11:11
 */
@Service
@Slf4j
public class AuthServiceImpl implements AuthService {

    @Autowired
    private UserService userService;

    @Autowired
    private MailService mailService;

    @Override
    public LoginResponse login(LoginParams params) {
        if (StrUtil.isBlank(params.getAccount())) {
            throw new IllegalArgumentException("请输入账号");
        }
        if (StrUtil.isBlank(params.getPassword())) {
            throw new IllegalArgumentException("请输入密码");
        }
        User user = userService.exists(params);
        Assert.notNull(user, "账号或密码不正确");
        return new LoginResponse()
                .setToken(JwtUtil.createToken(user.getUserId()))
                .setUserInfo(user.getUserId().toString());
    }

    @Override
    public LoginResponse register(LoginParams params) {
        User user = userService.init(params);
        return new LoginResponse()
                .setToken(JwtUtil.createToken(user.getUserId()))
                .setUserInfo(user.getUserId().toString());
    }

    @Override
    public void modifyPwd(LoginParams params) {
        verifyCode(params);
        if (StrUtil.isBlank(params.getAccount())) {
            throw new IllegalArgumentException("账号不能为空");
        }
        if (StrUtil.isBlank(params.getPassword())) {
            throw new IllegalArgumentException("密码不能为空");
        }
        userService.modifyPwd(params);
    }

    @Override
    public UserDetail userInfo(ServerWebExchange exchange) {
        UserPermission.UserInfo userInfo = UserPermission.get(exchange);
        if (userInfo == null) {
            return null;
        }
        User user = userService.findByUserId(userInfo.getUserId());
        return new UserDetail()
                .setUserId(user.getUserId())
                .setToken(userInfo.getToken())
                .setName(user.getName())
                .setRole(user.getRole());
    }

    @Override
    public Boolean sendVerifyCode(LoginParams params) {
        checkParams(params);
        return sendLoginVerifyCode(params);
    }

    private Boolean sendLoginVerifyCode(LoginParams params) {
        String verifyCode = generateVerifyCode();
        String title = "【Tool4j】--您的验证码";
        String content = "您的验证码是 " + verifyCode + " \n有效期5分钟，请勿泄露与他人。";
        mailService.sendMail(params.getEmail(), title, content);
        CacheUtil.setCache(Constants.AUTH_VERIFY_CODE_KEY + params.getEmail(), verifyCode);
        return true;
//        if (LoginTypeEnum.PHONE_NUM.getValue().equals(params.getType())) {
//            String verifyCode = generateVerifyCode();
//            SendSmsUtil.sendVerifyCode(params.getPhoneNum(), verifyCode);
//            CacheUtil.setCache(Constants.AUTH_VERIFY_CODE_KEY + params.getPhoneNum(), verifyCode);
//            return true;
//        } else if (LoginTypeEnum.EMAIL.getValue().equals(params.getType())) {
//            String verifyCode = generateVerifyCode();
//            String title = "【Tool4j】--您的登录验证码";
//            String content = "您的验证码是 " + verifyCode + " \n有效期5分钟，您正在使用验证码登录，请勿泄露与他人。";
//            mailService.sendMail(params.getEmail(), title, content);
//            CacheUtil.setCache(Constants.AUTH_VERIFY_CODE_KEY + params.getEmail(), verifyCode);
//            return true;
//        } else {
//            return false;
//        }
    }

    /**
     * 生成6位验证码
     *
     * @return
     */
    private static String generateVerifyCode() {
        StringBuilder code = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < 6; i++) {
            code.append(random.nextInt(10));
        }
        return code.toString();
    }

    /**
     * 校验验证码
     *
     * @param params
     */
    private void verifyCode(LoginParams params) {
        if (SpringUtil.isDev()) {
            return;
        }
        //校验验证码
        String contactNum;
        if (LoginTypeEnum.PHONE_NUM.getValue().equals(params.getType())) {
            contactNum = params.getPhoneNum();
        } else if (LoginTypeEnum.EMAIL.getValue().equals(params.getType())) {
            contactNum = params.getEmail();
        } else {
            return;
        }
        if ("15502791235".equals(contactNum) && "941216".equals(params.getVerifyCode())) {
            return;
        }
        String verifyKey = Constants.AUTH_VERIFY_CODE_KEY + contactNum;
        String verifyCode = CacheUtil.getCache(verifyKey);
        Assert.isTrue(StrUtil.isNotBlank(verifyCode) && params.getVerifyCode().equals(verifyCode), "验证码不正确或已过期！");
        CacheUtil.removeCache(verifyKey);
    }

    /**
     * 校验参数
     *
     * @param params
     */
    private void checkParams(LoginParams params) {
        //校验邮箱
        Pattern emailPattern = Pattern.compile("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$");
        Matcher emailMatcher = emailPattern.matcher(params.getPhoneNum());
        Assert.isTrue(emailMatcher.matches(), "邮箱格式不正确");
        params.setEmail(params.getPhoneNum());
        params.setType(LoginTypeEnum.EMAIL.getValue());
        //校验手机号或邮箱
//        Pattern phonePattern = Pattern.compile("^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$");
//        Matcher phoneMatcher = phonePattern.matcher(params.getPhoneNum());
//        if (phoneMatcher.matches()) {
//            params.setPhoneNum(params.getPhoneNum());
//            params.setType(LoginTypeEnum.PHONE_NUM.getValue());
//        } else {
//            Pattern emailPattern = Pattern.compile("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$");
//            Matcher emailMatcher = emailPattern.matcher(params.getPhoneNum());
//            Assert.isTrue(emailMatcher.matches(), "手机号或邮箱格式不正确");
//            params.setEmail(params.getPhoneNum());
//            params.setType(LoginTypeEnum.EMAIL.getValue());
//        }
    }

}